/*************************************************************************
	> File Name: 006.printf简版实现_v3.c
	> Author: Maureen 
	> Mail: Maureen@qq.com 
	> Created Time: 一  8/23 09:31:27 2021
 ************************************************************************/

#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>

//解决v2版本中INT32_MAX翻转后超出int范围的问题


int reverse_num(int num, int *temp) {
    int digit = 0;
    do {
        *temp = *temp * 10 + num % 10;
        num /= 10;
        digit++;
    } while (num);
    return digit;
}

int output_num(int num, int digit) {
    int cnt = 0;
    while (digit--) {
        putchar(num % 10 + 48);
        num /= 10;
        cnt++;
    }
    return cnt;
}

int my_printf(const char *frm, ...) {
    va_list arg;
    va_start(arg, frm);
    int cnt = 0;
    #define PUTC(a) putchar(a), ++cnt
    for (int i = 0; frm[i]; i++) {
        switch (frm[i]) {
            case '%': {
                switch (frm[++i]) {
                    case '%': {
                        PUTC(frm[i]);
                    } break;
                    case 'd': {
                        int xx = va_arg(arg, int);
                        uint32_t x; //用无符号整型处理极小值
                        if (xx < 0) PUTC('-'), x = -xx;
                        else x = xx;
                        //num1是高五位，num2是低五位
                        int num1 = x / 100000, num2 = x % 100000;
                        int temp1 = 0, temp2 = 0;
                        int digit1 = reverse_num(num1, &temp1);
                        int digit2 = reverse_num(num2, &temp2);
                        if (num1) digit2 = 5; //如果digit不为0，则一定存在低五位
                        else digit1 = 0;
                        cnt += output_num(temp1, digit1);
                        cnt += output_num(temp2, digit2);
                    } break;
                    case 's': {
                        const char *str = va_arg(arg, const char *);
                        for (int i = 0; str[i]; i++) {
                            PUTC(str[i]);
                        }
                    } break;
                }
            } break;
            default: PUTC(frm[i]); break;
        }
    }
    #undef PUTC 
    va_end(arg);
    return cnt;
}

int main() {
    int a = 123;
    //1.打印字符串
    printf("Hello world\n");
    my_printf("Hello world\n");
    //2.打印变量值
    printf("int a = %d\n", a);
    my_printf("int a = %d\n", a);

    printf("int a = %d\n", 1000);
    my_printf("int a = %d\n", 1000);

    printf("int a = %d\n", 0);
    my_printf("int a = %d\n", 0);

    printf("int a = %d\n", -123);
    my_printf("int a = %d\n", -123);

    printf("INT32_MAX = %d\n", INT32_MAX);
    my_printf("INT32_MAX = %d\n", INT32_MAX);//翻转后超出int能表示的范围了

    printf("INT32_MIN = %d\n", INT32_MIN);
    my_printf("INT32_MIN = %d\n", INT32_MIN);

    int n;
    char str[] = "I love China";
    printf("%s\n", str);
    my_printf("%s\n", str);
    while (~scanf("%d", &n)) {
        printf(" has %d digits!\n", printf("%d", n));
        my_printf(" has %d digits!\n", my_printf("%d", n));
    }

    return 0;
}
